home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Storage / LinkSpec.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  11.0 KB  |  398 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkSpec.cpp
  3.  
  4.     Contains:    Implementation for ODLinkSpec class.
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  13.  
  14.     To Do:
  15.     In Progress:
  16.         
  17. */
  18.  
  19. #define VARIABLE_MACROS
  20.  
  21. #define ODLinkSpec_Class_Source
  22. #include <LinkSpec.xih>
  23.  
  24. #ifndef SOM_Module_OpenDoc_StdProps_defined
  25. #include "StdProps.xh"
  26. #endif
  27.  
  28. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  29. #include "StdTypes.xh"
  30. #endif
  31.  
  32. #ifndef SOM_ODDraft_xh
  33. #include "Draft.xh"
  34. #endif
  35.  
  36. #ifndef SOM_ODStorageUnit_xh
  37. #include "StorageU.xh"
  38. #endif
  39.  
  40. #ifndef _EXCEPT_
  41. #include "Except.h"
  42. #endif
  43.  
  44. #ifndef _ODMEMORY_
  45. #include "ODMemory.h"
  46. #endif
  47.  
  48. #ifndef __ERRORS__
  49. #include <Errors.h>
  50. #endif
  51.  
  52. #ifndef _BARRAY_
  53. #include <BArray.h>
  54. #endif
  55.  
  56. #ifndef _STDTYPIO_
  57. #include <StdTypIO.h>
  58. #endif
  59.  
  60. #ifndef _TEMPOBJ_
  61. #include <TempObj.h>
  62. #endif
  63.  
  64. #ifndef _STORUTIL_
  65. #include <StorUtil.h>
  66. #endif
  67.  
  68. #ifndef _UTILERRS_
  69. #include "UtilErrs.h"
  70. #endif
  71.  
  72. #pragma segment ODLinkSpec
  73.  
  74. //==============================================================================
  75. // Constants
  76. //==============================================================================
  77. const ODULong kLinkSpecVersion = 1;    // Second version
  78.  
  79. // •••• kODSourcePartKey also defined for Drag & Drop ••••
  80. // •••• These don't belong here ••••
  81. #define kODProcessLaunchDateKey    'pldt'
  82. #define kODSourcePartKey            'part'
  83. #define kODLinkSpecDataKey            'data'
  84. #define kODLinkSpecDataSizeKey        'size'
  85. #define kODLinkSpecVersionKey        'vers'
  86.  
  87. //==============================================================================
  88. // ODLinkSpec
  89. //==============================================================================
  90.  
  91. //------------------------------------------------------------------------------
  92. // ODLinkSpec::somUninit
  93. //------------------------------------------------------------------------------
  94.  
  95. SOM_Scope void  SOMLINK ODLinkSpecsomUninit(ODLinkSpec *somSelf)
  96. {
  97.     /* ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf); */
  98.     ODLinkSpecMethodDebug("ODLinkSpec","somUninit");
  99.  
  100.     parent_somUninit(somSelf);
  101. }
  102.  
  103. //------------------------------------------------------------------------------
  104. // ODLinkSpec::InitLinkSpec
  105. //------------------------------------------------------------------------------
  106.  
  107. SOM_Scope void  SOMLINK ODLinkSpecInitLinkSpec(ODLinkSpec *somSelf, Environment *ev,
  108.         ODPart* part,
  109.         ODByteArray* partData)
  110. {
  111.     ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf);
  112.     ODLinkSpecMethodDebug("ODLinkSpec","InitLinkSpec");
  113.  
  114.     SOM_TRY
  115.  
  116.     /* Moved from somInit. SOM itself sets fields to zero 
  117.     _fProcessLaunchDate = 0;
  118.     */
  119.     _fProcessID.lowLongOfPSN = kNoProcess;
  120.     _fProcessID.highLongOfPSN = 0;
  121.     
  122.     somSelf->InitBaseLinkSpec(ev, part, partData);
  123.  
  124.     if ( part )
  125.     {
  126.         ProcessSerialNumber psn;
  127.         ProcessInfoRec myProcessInfo;
  128.         
  129.         psn.lowLongOfPSN = kCurrentProcess;
  130.         psn.highLongOfPSN = 0;
  131.         myProcessInfo.processAppSpec = NULL;
  132.         myProcessInfo.processName = NULL;
  133.         myProcessInfo.processInfoLength = sizeof(myProcessInfo);
  134.         
  135.         OSErr error = GetProcessInformation(&psn, &myProcessInfo);
  136.         ASSERT((error == 0), kODErrAssertionFailed);
  137.     
  138.         _fProcessID = myProcessInfo.processNumber;
  139.         _fProcessLaunchDate = myProcessInfo.processLaunchDate;
  140.     }
  141.  
  142.     SOM_CATCH_ALL
  143.     SOM_ENDTRY
  144. }
  145.  
  146. //------------------------------------------------------------------------------
  147. // ODLinkSpec::FromThisDraft (OVERRIDE)
  148. //------------------------------------------------------------------------------
  149.  
  150. SOM_Scope ODBoolean  SOMLINK ODLinkSpecFromThisDraft(ODLinkSpec *somSelf, Environment *ev)
  151. {
  152.     ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf);
  153.     ODLinkSpecMethodDebug("ODLinkSpec","FromThisDraft");
  154.  
  155.     SOM_TRY
  156.     
  157.     ProcessSerialNumber myPSN;
  158.     ProcessInfoRec myProcessInfo;
  159.     Boolean isSamePSN;
  160.     
  161.     myPSN.lowLongOfPSN = kCurrentProcess;
  162.     myPSN.highLongOfPSN = 0;
  163.     myProcessInfo.processAppSpec = NULL;
  164.     myProcessInfo.processName = NULL;
  165.     myProcessInfo.processInfoLength = sizeof(myProcessInfo);
  166.     THROW_IF_ERROR(GetProcessInformation(&myPSN, &myProcessInfo));
  167.     THROW_IF_ERROR(SameProcess(&_fProcessID, &myProcessInfo.processNumber, &isSamePSN));
  168.  
  169.     return (isSamePSN && (myProcessInfo.processLaunchDate == _fProcessLaunchDate));
  170.  
  171.     SOM_CATCH_ALL
  172.     SOM_ENDTRY
  173.     return kODFalse;
  174. }
  175.  
  176. //------------------------------------------------------------------------------
  177. // ODLinkSpec::GetOriginatingProcessID
  178. //------------------------------------------------------------------------------
  179.  
  180. SOM_Scope void  SOMLINK ODLinkSpecGetOriginatingProcessID(ODLinkSpec *somSelf, Environment *ev,
  181.         ProcessSerialNumber *psn)
  182. {
  183.     ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf);
  184.     ODLinkSpecMethodDebug("ODLinkSpec","GetProcessLaunchDate");
  185.  
  186.     ProcessInfoRec info;
  187.     
  188.     info.processAppSpec = NULL;
  189.     info.processName = NULL;
  190.     info.processInfoLength = sizeof(info);
  191.  
  192.     if ( (GetProcessInformation(&_fProcessID, &info) == noErr) &&
  193.             (info.processLaunchDate == _fProcessLaunchDate) )
  194.     {
  195.         *psn = _fProcessID;
  196.     }
  197.     else
  198.     {
  199.         psn->lowLongOfPSN = kNoProcess;
  200.         psn->highLongOfPSN = 0;
  201.         ODSetSOMException(ev, kODErrCannotGetExternalLink);
  202.     }
  203. }
  204.  
  205. //------------------------------------------------------------------------------
  206. // ODLinkSpec::WriteLinkSpec (OVERRIDE)
  207. //------------------------------------------------------------------------------
  208.  
  209. SOM_Scope void  SOMLINK ODLinkSpecWriteLinkSpec(ODLinkSpec *somSelf, Environment *ev,
  210.         ODStorageUnit* su)
  211. {
  212.     ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf);
  213.     ODLinkSpecMethodDebug("ODLinkSpec","WriteLinkSpec");
  214.  
  215.     SOM_TRY
  216.  
  217.     ODVolatile(su);
  218.  
  219.     ODULong version = kLinkSpecVersion;
  220.     ODULong size;
  221.  
  222.     ODSUForceFocus(ev, su, kODNULL, kODLinkSpec);
  223.     size = su->GetSize(ev);
  224.     su->DeleteValue(ev, size);
  225.  
  226.     TRY
  227.         StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue) &version);
  228.         StorageUnitSetValue(su, ev, sizeof(ProcessSerialNumber), (ODValue) &_fProcessID);
  229.         StorageUnitSetValue(su, ev, sizeof(ODULong), (ODValue) &_fProcessLaunchDate);
  230.  
  231.         parent_WriteLinkSpec(somSelf, ev, su);
  232.     CATCH_ALL
  233.         su->Remove(ev);
  234.         RERAISE;
  235.     ENDTRY
  236.  
  237.     SOM_CATCH_ALL
  238.     SOM_ENDTRY
  239. }
  240.  
  241. //------------------------------------------------------------------------------
  242. // ODLinkSpec::ReadLinkSpec (OVERRIDE)
  243. //------------------------------------------------------------------------------
  244.  
  245. SOM_Scope void  SOMLINK ODLinkSpecReadLinkSpec(ODLinkSpec *somSelf, Environment *ev,
  246.         ODStorageUnit* su)
  247. {
  248.     ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf);
  249.     ODLinkSpecMethodDebug("ODLinkSpec","ReadLinkSpec");
  250.  
  251.     SOM_TRY
  252.  
  253.     ODULong                version;
  254.     ProcessSerialNumber processID;
  255.     ODULong                processLaunchDate;
  256.     ODULong                valueSize;
  257.  
  258.     // Pre-focused property must contain a link spec value
  259.     if (!ODSUExistsThenFocus(ev, su, (ODPropertyName) kODNULL, kODLinkSpec))
  260.         THROW(kODErrNoLinkSpecValue);
  261.  
  262.     StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue) &version);
  263.     if (version != kLinkSpecVersion) 
  264.         THROW(kODErrUnknownLinkSpecVersion);
  265.  
  266.     valueSize = StorageUnitGetValue(su, ev, sizeof(ProcessSerialNumber), (ODValue) &processID);
  267.     if ( valueSize != sizeof(ProcessSerialNumber) )
  268.         THROW(kODErrCorruptLinkSpecValue);
  269.  
  270.     valueSize = StorageUnitGetValue(su, ev, sizeof(ODULong), (ODValue) &processLaunchDate);
  271.     if ( valueSize != sizeof(ODULong) )
  272.         THROW(kODErrCorruptLinkSpecValue);
  273.  
  274.     parent_ReadLinkSpec(somSelf, ev, su);
  275.  
  276.     _fProcessID = processID;
  277.     _fProcessLaunchDate = processLaunchDate;
  278.  
  279.     SOM_CATCH_ALL
  280.     SOM_ENDTRY
  281. }
  282.  
  283. //------------------------------------------------------------------------------
  284. // ODLinkSpec::WriteToAppleEvent
  285. //------------------------------------------------------------------------------
  286.  
  287. SOM_Scope void  SOMLINK ODLinkSpecWriteToAppleEvent(ODLinkSpec *somSelf, Environment *ev,
  288.         AppleEvent* theAppleEvent)
  289. {
  290.     ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf);
  291.     ODLinkSpecMethodDebug("ODLinkSpec","WriteToAppleEvent");
  292.     
  293.     SOM_TRY
  294.  
  295.     OSErr error;
  296.     ODPart* part = somSelf->GetPart(ev);
  297.     ODByteArray partData = somSelf->GetPartData(ev);
  298.  
  299.     ODULong version = kLinkSpecVersion;
  300.     error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecVersionKey, typeLongInteger,
  301.                         &version, sizeof(version));
  302.  
  303.     if ( error == noErr )
  304.         error = AEPutParamPtr((AppleEvent*) theAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber,
  305.                             &_fProcessID, sizeof(_fProcessID));
  306.  
  307.     if ( error == noErr )
  308.         error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODProcessLaunchDateKey, typeLongInteger,
  309.                             &_fProcessLaunchDate, sizeof(_fProcessLaunchDate));
  310.  
  311.     if ( error == noErr )
  312.         error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODSourcePartKey, typeLongInteger,
  313.                             &part, sizeof(part));
  314.  
  315.     if ( error == noErr )
  316.         error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataSizeKey, typeLongInteger,
  317.                             &partData._length, sizeof(ODULong));
  318.  
  319.     if ( (error == noErr) && (partData._length > 0) )
  320.         error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataKey, typeChar /* ••• need better type here •••• */,
  321.                             partData._buffer, partData._length);
  322.     
  323.     DisposeByteArrayStruct(partData);
  324.  
  325.     THROW_IF_ERROR(error);
  326.     
  327.     SOM_CATCH_ALL
  328.     SOM_ENDTRY
  329. }
  330.  
  331. //------------------------------------------------------------------------------
  332. // ODLinkSpec::ReadFromAppleEvent
  333. //------------------------------------------------------------------------------
  334.  
  335. SOM_Scope void  SOMLINK ODLinkSpecReadFromAppleEvent(ODLinkSpec *somSelf, Environment *ev,
  336.         AppleEvent* theAppleEvent)
  337. {
  338.     ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf);
  339.     ODLinkSpecMethodDebug("ODLinkSpec","ReadFromAppleEvent");
  340.  
  341.     SOM_TRY
  342.  
  343.     /* Moved from somInit. SOM itself sets fields to zero 
  344.     _fProcessLaunchDate = 0;
  345.     _fProcessID.lowLongOfPSN = kNoProcess;
  346.     _fProcessID.highLongOfPSN = 0;
  347.     */
  348.     
  349.     OSErr                result;
  350.     DescType            returnedType;
  351.     Size                actualSize;
  352.     ODPart*                part;
  353.     ODByteArray            partData;
  354.     ProcessSerialNumber processID;
  355.     ODULong                processLaunchDate;
  356.     ODULong                dataSize;
  357.  
  358.     result = AEGetParamPtr((AppleEvent*) theAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber, &returnedType,
  359.                             &processID, sizeof(processID), &actualSize);
  360.     THROW_IF_ERROR(result);
  361.  
  362.     result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODProcessLaunchDateKey, typeLongInteger, &returnedType,
  363.                             &processLaunchDate, sizeof(processLaunchDate), &actualSize);
  364.     THROW_IF_ERROR(result);
  365.  
  366.     result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODSourcePartKey, typeLongInteger, &returnedType,
  367.                             &part, sizeof(part), &actualSize);
  368.     THROW_IF_ERROR(result);
  369.  
  370.     result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataSizeKey, typeLongInteger, &returnedType,
  371.                             &dataSize, sizeof(ODULong), &actualSize);
  372.     THROW_IF_ERROR(result);
  373.     
  374.     partData = CreateEmptyByteArrayStruct(dataSize);
  375.  
  376.     TRY
  377.         if ( dataSize > 0 )
  378.         {
  379.             result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataKey, typeChar, &returnedType,
  380.                                     partData._buffer, dataSize, &actualSize);
  381.             THROW_IF_ERROR(result);
  382.             partData._length = dataSize;
  383.         }
  384.         somSelf->InitBaseLinkSpec(ev, part, &partData);
  385.     CATCH_ALL
  386.         DisposeByteArrayStruct(partData);
  387.         RERAISE;
  388.     ENDTRY
  389.  
  390.     DisposeByteArrayStruct(partData);
  391.     
  392.     _fProcessID = processID;
  393.     _fProcessLaunchDate = processLaunchDate;
  394.  
  395.     SOM_CATCH_ALL
  396.     SOM_ENDTRY
  397. }
  398.